# -*- coding: utf-8 -*-

from app import db

from flask_login import UserMixin

from werkzeug.security import check_password_hash, generate_password_hash


INIT_CASH = 1000000
FEE_RATE = 0.00025


class Strategy(db.Model):
    # 定义策略名称、费率、初始资金、起始、结束日期
    __tablename__ = 'strategy'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(40))
    # Excel出现在表头的名称
    title = db.Column(db.String(40))
    fee_rate = db.Column(db.Float)
    init_cash = db.Column(db.Integer)

    def __init__(self, name, title,
                 fee_rate=FEE_RATE,
                 init_cash=INIT_CASH):
        # 手续费率默认万分之2.5，初始资金100万
        self.name = name
        self.title = title
        self.fee_rate = fee_rate
        self.init_cash = init_cash

    def __repr__(self):
        return '%s(%r ,%r, %r)' % (self.__class__.__name__,
                                   self.id, self.name,
                                   self.title)


class DailyUpdate(db.Model):
    # 每天策略输入表格
    __tablename__ = 'daily_update'
    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.String(40))
    stockid = db.Column(db.String(20))
    # 策略ID
    sid = db.Column(db.Integer, db.ForeignKey('strategy.id'))
    strategy = db.relationship('Strategy',
                               backref=db.backref('daily_update',
                                                  lazy='dynamic'))

    def __init__(self, date, stockid, strategy):
        self.date = date
        self.stockid = stockid
        self.strategy = strategy

    def __repr__(self):
        return '%s(%r ,%r, %r)' % (self.__class__.__name__,
                                   self.sid,
                                   self.date,
                                   self.stockid)


class TradingRecord(db.Model):
    # 模拟交易记录
    __tablename__ = 'trading_record'
    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.String(20))
    stockid = db.Column(db.String(20))
    price = db.Column(db.Float)
    # 数量
    amount = db.Column(db.Integer)
    # 成交额
    trans = db.Column(db.Float)
    # 手续费
    fee = db.Column(db.Float)
    sid = db.Column(db.Integer, db.ForeignKey('strategy.id'))
    strategy = db.relationship('Strategy',
                               backref=db.backref('trading_record',
                                                  lazy='dynamic'))

    def __init__(self, date, stockid, price, amount, trans,
                 fee, strategy):
        self.date = date
        self.stockid = stockid
        self.price = price
        self.amount = amount
        self.trans = trans
        self.fee = fee
        self.strategy = strategy

    def __repr__(self):
        return '%s(%r ,%r, %r, %r)' % (self.__class__.__name__,
                                       self.sid, self.date,
                                       self.price, self.amount)


class DailyAsset(db.Model):
    # 模拟交易记录
    __tablename__ = 'daily_asset'
    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.String(20))
    cash = db.Column(db.Float)
    holding = db.Column(db.Float)
    asset = db.Column(db.Float)

    sid = db.Column(db.Integer, db.ForeignKey('strategy.id'))
    strategy = db.relationship('Strategy',
                               backref=db.backref('daily_asset',
                                                  lazy='dynamic'))

    def __init__(self, date, cash, holding, asset, strategy):
        self.date = date
        self.cash = cash
        self.holding = holding
        self.asset = asset
        self.strategy = strategy

    def __repr__(self):
        return '%s(%r ,%r, %r, %r, %r)' % (self.__class__.__name__,
                                           self.sid, self.date, self.cash,
                                           self.holding, self.asset)


# 用户表
class User(UserMixin, db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))

    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def __init__(self, username, password):
        self.username = username
        self.password = password

    def is_authenticated(self):
        return True

    def is_active():
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return self.id

    def __repr__(self):
        return '%s' % self.username


# 交易账户表
class Account(db.Model):
    __tablename__ = 'account'
    id = db.Column(db.Integer, primary_key=True)
    account = db.Column(db.String(40))
    name = db.Column(db.String(20))
    futures = db.Column(db.String(40))

    def __init__(self, account, name, futures):
        self.account = account
        self.name = name
        self.futures = futures

    def __repr__(self):
        return '%s(%r ,%r, %r, %r)' % (self.__class__.__name__, self.account,
                                       self.name, self.futures)


# 收盘持仓表，将每天收盘的持仓记录在此
class Holding(db.Model):
    __tablename__ = 'holding'
    id = db.Column(db.Integer, primary_key=True)
    # 日期时间字符串形式
    dt = db.Column(db.String(40))
    name = db.Column(db.String(20))
    stockid = db.Column(db.String(40))
    price = db.Column(db.Integer)
    amount = db.Column(db.Integer)

    sid = db.Column(db.Integer, db.ForeignKey('strategy.id'))
    strategy = db.relationship('Strategy',
                               backref=db.backref('holding',
                                                  lazy='dynamic'))

    def __init__(self, dt, name, stockid, price, amount, strategy):
        self.dt = dt
        self.name = name
        self.stockid = stockid
        self.price = price * 1000
        self.amount = amount
        self.strategy = strategy

    def __repr__(self):
        return '%s(%r ,%r, %r, %r, %r)' % (self.__class__.__name__,
                                           self.dt,
                                           self.name,
                                           self.stockid,
                                           self.price,
                                           self.amount)


# 动态持仓表，买入操作后，放入此表
class DynamicHolding(db.Model):
    __tablename__ = 'dynamic_holding'
    id = db.Column(db.Integer, primary_key=True)
    # 日期时间字符串形式
    dt = db.Column(db.String(40))
    name = db.Column(db.String(20))
    stockid = db.Column(db.String(40))
    price = db.Column(db.Float)
    amount = db.Column(db.Integer)

    sid = db.Column(db.Integer, db.ForeignKey('strategy.id'))
    strategy = db.relationship('Strategy',
                               backref=db.backref('dynamic_holding',
                                                  lazy='dynamic'))

    def __init__(self, dt, name, stockid, price, amount, strategy):
        self.dt = dt
        self.name = name
        self.stockid = stockid
        self.price = price
        self.amount = amount
        self.strategy = strategy

    def __repr__(self):
        return '%s(%r ,%r, %r, %r, %r)' % (self.__class__.__name__,
                                           self.dt,
                                           self.name,
                                           self.stockid,
                                           self.price,
                                           self.amount)


